package com.lqzs.businessmanager.service

import android.accessibilityservice.AccessibilityService.GestureResultCallback
import android.accessibilityservice.GestureDescription
import android.accessibilityservice.GestureDescription.StrokeDescription
import android.annotation.SuppressLint
import android.graphics.Path
import android.os.Build
import android.os.Handler
import android.os.Looper
import android.text.TextUtils
import android.util.Log
import android.view.View
import android.view.accessibility.AccessibilityNodeInfo
import android.widget.EditText
import android.widget.ScrollView
import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.lifecycle.viewModelScope
import com.lqzs.businessmanager.Config
import com.lqzs.businessmanager.Config.Companion.SCROLL_TIMER
import com.lqzs.businessmanager.Config.Companion.SCROLL_TIMER_LONG
import com.lqzs.businessmanager.base.BaseViewModel
import com.lqzs.businessmanager.bean.AccessInfo
import com.lqzs.businessmanager.bean.response.ReviewInfoResponse
import com.lqzs.businessmanager.dao.AccessDao
import com.lqzs.businessmanager.dao.AccessDataBase
import com.lqzs.businessmanager.dao.ReplyDao
import com.lqzs.businessmanager.http.HttpUtils
import com.lqzs.businessmanager.http.RetrofitService
import com.lqzs.businessmanager.http.addReviewInfo
import com.lqzs.businessmanager.http.makeRequest
import com.lqzs.businessmanager.http.updateOrderInfo
import com.lqzs.businessmanager.service.AccessibilitySampleService.Companion.TAG
import com.lqzs.businessmanager.utils.PreferencesUtil
import com.lqzs.businessmanager.utils.StringUtils
import com.lqzs.businessmanager.utils.StringUtils.getTime
import com.lqzs.businessmanager.utils.clickReply
import com.lqzs.businessmanager.utils.clickSelector
import com.lqzs.businessmanager.utils.clickTimer
import com.lqzs.businessmanager.utils.clickTimerSix
import com.lqzs.businessmanager.utils.clickViewReplay
import com.lqzs.businessmanager.utils.closeAfterSalesDialog
import com.lqzs.businessmanager.utils.closeDialog
import com.lqzs.businessmanager.utils.closeSoundDialog
import com.lqzs.businessmanager.utils.nodeOnClick
import com.lqzs.businessmanager.utils.setEditText
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicInteger

/**
 * 美团事件处理
 */
@Suppress("DEPRECATED_IDENTITY_EQUALS", "DEPRECATION")
class MeiTuanViewModel : BaseViewModel() {
    companion object{
        val TAG: String = MeiTuanViewModel::class.java.name
    }
    @SuppressLint("StaticFieldLeak")
    private lateinit var mService: AccessibilitySampleService
    private lateinit var accessDao: AccessDao
    private lateinit var replyDao: ReplyDao
    private lateinit var mRetrofitService: RetrofitService

    private var scrollViewNodeInfo :AccessibilityNodeInfo?=null
    var replayStatus = Config.IS_REPLAY
    private val mHandler = Handler(Looper.getMainLooper())
    @Volatile
    var scrollNum = 0//是否有滑动事件

    @Volatile
    var isScrollBottom = 0 //是否滑动到底部

    private var isClickViewReplay = AtomicInteger(0) //是否有回复点击

    private var isClickRepay = AtomicBoolean(true)

    private val mutex = Mutex()
    private val mCurrentMapSet = ConcurrentHashMap<String,LinkedHashSet<String>>()
    private var editTextInfo: ReviewInfoResponse? = null

    @RequiresApi(Build.VERSION_CODES.O)
    fun init(service: AccessibilitySampleService){
        mService = service
        accessDao = AccessDataBase.getDataBase().accessDao()
        replyDao = AccessDataBase.getDataBase().replayDao()
        mRetrofitService = HttpUtils.getInstance().create()
        upload()
    }

    fun editTextDialogDismiss(){
        //路径点击
        val path = Path()
        //, Y:
        path.moveTo(216.23f, 215.18f) // 假设的起始坐标
        path.lineTo(216.23f, 215.18f) // 点击操作，起点和终点相同
        val stroke = StrokeDescription(path, 0, 100)
        val gesture = GestureDescription.Builder().addStroke(stroke).build()
        // 执行手势
        mService.dispatchGesture(gesture, object : GestureResultCallback() {
            override fun onCompleted(gestureDescription: GestureDescription) {
                Log.e(TAG,"点击取消回复弹窗")
            }

            override fun onCancelled(gestureDescription: GestureDescription) {
                // 手势取消时调用
            }
        }, null) // 手势执行的 Handler，传 null 表示在主线程执行
    }


    /**
     * 美团外卖商家数据相关处理
     */
    suspend fun handlerMeiTuan(rowNode: AccessibilityNodeInfo){

        if (rowNode.className == null)
            return
        for(i in 0 until rowNode.childCount){

            //如果便利节点为空则跳出
            val rootClassName = rowNode.className ?:continue
            val  childNodeInfo = rowNode.getChild(i) ?: continue
            val className = childNodeInfo.className ?: continue

            if (closeDialog(childNodeInfo)){
                childNodeInfo.recycle()
                return
            }
            if (closeSoundDialog(childNodeInfo,rowNode.getChild(i))){
                childNodeInfo.recycle()
                return
            }
            /**
             * 关闭售后提醒弹窗
             */
            if (closeAfterSalesDialog(childNodeInfo)){
                childNodeInfo.recycle()
                return
            }

            /**
             * 选择是否回复
             */
            if (!PreferencesUtil.getBoolean(mService,Config.YES_REPLAY)){
                if (isClickRepay.get()){
                    if (clickReply(childNodeInfo,replayStatus)){
                        isClickRepay.set(false)
                        childNodeInfo.refresh()
                        return
                    }
                }
                //已回复是否读取
                clickViewReplay(childNodeInfo,Config.YES_REPLAY)?.let {
                    replayStatus = it
                    scrollNum=0
                    isScrollBottom = 0
                    isClickViewReplay.set(0)
                    childNodeInfo.refresh()
                    mCurrentMapSet.clear()
                    return
                }
            }else if (!PreferencesUtil.getBoolean(mService,Config.NO_REPLAY)){
                if (isClickRepay.get()){
                    if (clickReply(childNodeInfo,replayStatus)){
                        isClickRepay.set(false)
                        childNodeInfo.refresh()
                        return
                    }
                }
                clickViewReplay(childNodeInfo,Config.NO_REPLAY)?.let {
                    replayStatus = it
                    scrollNum=0
                    isScrollBottom = 0
                    isClickViewReplay.set(0)
                    childNodeInfo.refresh()
                    mCurrentMapSet.clear()
                    return
                }
            }

            /**
             * 选择时间
             */
            if (!PreferencesUtil.getBoolean(mService,Config.BUSINESS_SIX_MONTH,false)){
                if (clickTimer(childNodeInfo)){
                    childNodeInfo.recycle()
                    return
                }
                if (clickTimerSix(childNodeInfo)){
                    scrollNum = 0
                    childNodeInfo.recycle()
                    return
                }
            }

            if (clickSelector(childNodeInfo)){
                replayStatus = Config.IS_REPLAY
                scrollNum = 0
                isScrollBottom = 0
                isClickViewReplay.set(0)
                isClickRepay.set(false)
                mCurrentMapSet.clear()
                PreferencesUtil.putBoolean(mService,Config.NO_REPLAY,true)
                PreferencesUtil.putBoolean(mService,Config.BUSINESS_SIX_MONTH,true)
                childNodeInfo.recycle()
                return
            }
            /**
             * 点击回复按钮后弹出弹窗
             */
            if (className == EditText::class.java.name ){
                if (editTextInfo!=null){
                    editTextInfo?.let {
                        if (setEditText(childNodeInfo, rowNode.getChild(rowNode.childCount-1), it, accessDao)){
                            editTextInfo = null
                            isClickRepay.set(true)
                            isClickViewReplay.set(0)
                            scrollViewNodeInfo?.let {node ->
                                if (replayStatus.contains(Config.YES_REPLAY)){
                                    scrollAddData(node)
                                }else{
                                    scrollNoReplayData(node)
                                }
                            }
                        }
                    }
                }else{
                    editTextDialogDismiss()
                }
            }

            /**
             * 只有一条数据的情况处理
             */
            childNodeInfo.contentDescription?.let {
                if (childNodeInfo.childCount>1){
                    val mList = ArrayList<String>()
                    for (j in 0 until childNodeInfo.childCount){
                        val child = childNodeInfo.getChild(j)?:continue
                        val content = child.contentDescription?:continue
                        mList.add(content.toString().trim())
                    }
                    if (mList.contains("联系顾客")
                        && mList.contains("回复")
                        && mList.contains("申诉")){
                        mList.clear()
                        val contentDescription = childNodeInfo.contentDescription
                        if (contentDescription!=null){
                            queryNoReplayChild(childNodeInfo,
                                contentDescription.toString().trim(),
                                null,false)
                        }
                    }
                }
            }

            if (className == ScrollView::class.java.name) {
                scrollViewNodeInfo = childNodeInfo
                if (replayStatus.contains(Config.YES_REPLAY)){
                    scrollAddData(childNodeInfo)
                }else{
                    scrollNoReplayData(childNodeInfo)
                }
            }else{
                handlerMeiTuan(childNodeInfo)
            }
        }
    }

    /**
     * 开启协程上传后台
     */
    private fun upload() {
        viewModelScope.launch(Dispatchers.IO) {
            val all = accessDao.queryNoUpload()
            if (all.isEmpty()){
                delay(5000L)
                upload()
            }else{
                val time = PreferencesUtil.getString(mService,Config.LAST_PINGLUN_TIME)
                val content = PreferencesUtil.getString(mService,Config.LAST_PINGLUN_CONTENT)
                for (i in all.indices){
                    val info = all[i]
                    when(info.upload){
                        0->{
                            if (!TextUtils.isEmpty(info.merchantReplied)){
                                val addReviewInfo = makeRequest(addReviewInfo(info))
                                addReviewInfo?.let {
                                    if (info.orderDetails == "订单详情：为保护用户隐私，订单完成后48小时后才会展示订单详情"){
                                        info.upload = 3
                                    }else{
                                        info.upload = 1
                                    }
                                    info.reviewId = it.review_id
                                    accessDao.update(info)
                                }
                                if (addReviewInfo == null) {
                                    accessDao.delete(info)
                                }
                            }
                        }
                        3->{
                            if (info.orderDetails!="订单详情：为保护用户隐私，订单完成后48小时后才会展示订单详情"){
                                val addReviewInfo = makeRequest(updateOrderInfo(mService,info))
                                addReviewInfo?.let {
                                    info.upload = 1
                                    accessDao.update(info)
                                }
                                if (addReviewInfo == null) {
                                    accessDao.delete(info)
                                }
                            }
                        }
                    }
//            try{
//                if (info.time!=null&&time.isNotEmpty()&&StringUtils.compareDateStrings(info.time!!,time)<0){
//                    continue
//                }
//            }catch (e: DateTimeParseException){
//                Log.e(TAG,"时间转换异常：$e")
//            }
                    if (i == all.size-1){
                        all.clear()
                        upload()
                    }
                }
            }
        }
    }

    /**
     * 滑动未回复数据
     * 首先判断是否滑动到底部
     * 滑动到底部通过判断最后一条的位置<1400
     */
    suspend fun scrollNoReplayData(scrollNodeInfo : AccessibilityNodeInfo){
        mutex.withLock {
            for(i in 0 until scrollNodeInfo.childCount){
                val  childNodeInfo = scrollNodeInfo.getChild(i) ?: continue
                val nodeContent = childNodeInfo.contentDescription?:continue

                if (clickSelector(childNodeInfo)){
                    replayStatus = Config.IS_REPLAY
                    isScrollBottom = 0
                    PreferencesUtil.putBoolean(mService,Config.NO_REPLAY,true)
                    PreferencesUtil.putBoolean(mService,Config.BUSINESS_SIX_MONTH,true)
                    childNodeInfo.refresh()
                    return
                }
                val childContent = nodeContent.toString()

                if (isClickViewReplay.get() == 0) {
                    //是否是最后一条数据
                    val isLastChild = i === scrollNodeInfo.childCount - 1
                    //是否可以滑动
                    val shouldScroll = isLastChild && scrollNum == 0 && scrollNodeInfo.isScrollable

                    if (childNodeInfo.childCount > 1) {
                        queryNoReplayChild(childNodeInfo, childContent, scrollNodeInfo, isLastChild)
                    } else if (shouldScroll) {
                        // 滚动视图向下
                        uploadScroll(scrollNodeInfo, SCROLL_TIMER_LONG)
                    }
                }
            }
        }
    }

    private suspend fun queryNoReplayChild(childNodeInfo: AccessibilityNodeInfo, childContent: String,scrollNodeInfo: AccessibilityNodeInfo?,isScroll:Boolean) {
        Log.e("我的服务","注释掉回复");
        var huiFuNode :AccessibilityNodeInfo?=null
        val mHashSet = mCurrentMapSet[childContent]?: LinkedHashSet<String>().also { mCurrentMapSet[childContent] = it }
        for (j in 0 until childNodeInfo.childCount){
            val  viewNodeInfo = childNodeInfo.getChild(j) ?: continue
            val className = viewNodeInfo.className?: continue
            val viewContent = viewNodeInfo.contentDescription

            if (viewContent!=null){
                when {
                    viewContent.contains("订单详情") && viewContent.contains("...") -> {
                        nodeOnClick(viewNodeInfo)
                        viewNodeInfo.refresh()
                    }
                    className == View::class.java.name && (viewContent.toString().trim() == "回复" || viewContent.toString().trim() == "修改回复") -> {
                        if (viewNodeInfo.isClickable) huiFuNode = viewNodeInfo
                    }
                }

                mHashSet.add(viewContent.toString().trim())
            }

            if (j==childNodeInfo.childCount-1){
                val value = mCurrentMapSet[childContent]
                if (value!=null){
                    val accessInfo =  accessDao.query(childContent)?:AccessInfo().apply {
                        content = childContent
                        time = getTime(childContent)
                    }

                    for (setContent in value){
                        if (setContent == "回复"){
                            continue
                        }
                        if (setContent == "申诉"){
                            continue
                        }
                        if (setContent == "联系顾客"){
                            continue
                        }
                        if (setContent == "发券"){
                            continue
                        }
                        if (setContent == "修改回复"){
                            continue
                        }
                        if (setContent.contains("订单详情")){
                            accessInfo.orderDetails = setContent
                        }else {
                            if (setContent != "回复"){
                                if (childContent.contains("追评")
                                    &&accessInfo.chaseComments==null){
                                    accessInfo.chaseComments = setContent
                                }else{
                                    accessInfo.merchantReplied = setContent
                                }
                            }
                        }
                    }
                    val merchantReplied = accessInfo.merchantReplied
                    if (huiFuNode?.className == View::class.java.name && huiFuNode?.contentDescription.toString().trim() == "回复"){
                        accessInfo.merchantReplied = null
                        accessInfo.upload = 0
                    }
                    makeRequest(addReviewInfo(accessInfo))

                    var mReviewInfo = ReviewInfoResponse()
                    val name = accessInfo.content?.let { StringUtils.getName(it) }
                    val key = "$name@${accessInfo.time}"
                    val replyInfo = replyDao.query(key)
                    Log.d(TAG, "key $key reply ${replyInfo.toString()}")
                    if (replyInfo != null) {
                        mReviewInfo.review_id = replyInfo.reviewId
                        mReviewInfo.reply_content = replyInfo.replyContent
                        mReviewInfo.is_exist = true
                        mReviewInfo.state = replyInfo.state
                    }

                    if (mReviewInfo != null && huiFuNode != null && mReviewInfo.reply_content?.isNotEmpty() == true
                        && mReviewInfo.reply_content!=merchantReplied
                        &&huiFuNode.isVisibleToUser&& !childContent.contains("审核中")) {
                        accessInfo.upload = if (accessInfo.orderDetails == "订单详情：为保护用户隐私，订单完成后48小时后才会展示订单详情") 3 else 1
                        accessDao.insertOrUpdate(accessInfo)
                        editTextInfo = mReviewInfo
//                        nodeOnClick(huiFuNode)
//                        huiFuNode.refresh()
                        uploadScrollRunnable?.let {mRunnable->
                            mHandler.removeCallbacks(mRunnable)
                            uploadScrollRunnable =null
                        }
                        scrollNum = 0
                        isClickViewReplay.set(1)
                    } else if (isScroll && scrollNum == 0 && scrollNodeInfo?.isScrollable == true) {
                        uploadScroll(scrollNodeInfo, SCROLL_TIMER_LONG)
                    }
                }
            }
        }
    }


    private var uploadScrollRunnable : Runnable?=null
    fun uploadScroll(scrollNodeInfo: AccessibilityNodeInfo?,timer:Long){

        if (uploadScrollRunnable == null){
            uploadScrollRunnable = Runnable {
                scrollNum+=1
                if (isClickViewReplay.get()==0){
                    if (isScrollBottom == 0){
                        //滑动到底部进行判断
                        scrollNodeInfo?.performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD)
                        uploadScrollRunnable?.let {
                            mHandler.postDelayed(it,timer)
                        }
                        isScrollBottom++

                    }else{
                        scrollNodeInfo?.performAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD)
                        scrollNum = 0
                        uploadScrollRunnable?.let {
                            mHandler.removeCallbacks(it)
                            uploadScrollRunnable =null
                        }
                        PreferencesUtil.putBoolean(mService,Config.NO_REPLAY,false)
                        isClickRepay.set(true)
                    }
                }else{
                    uploadScrollRunnable?.let {
                        mHandler.postDelayed(it,timer)
                    }
                }
            }
            uploadScrollRunnable?.let {
                mHandler.postDelayed(it,timer)
            }
        }
    }

    /**
     * 检索数据添加本地数据库
     */
    suspend fun scrollAddData( scrollNodeInfo : AccessibilityNodeInfo){
        mutex.withLock {
            for(i in 0 until scrollNodeInfo.childCount){
                val  childNodeInfo = scrollNodeInfo.getChild(i) ?: continue
                val nodeContent = childNodeInfo.contentDescription?:continue
                val childContent = nodeContent.toString()
                if (clickSelector(childNodeInfo)){
                    replayStatus = Config.IS_REPLAY
                    isScrollBottom = 0
                    PreferencesUtil.putBoolean(mService,Config.YES_REPLAY,true)
                    PreferencesUtil.putBoolean(mService,Config.BUSINESS_SIX_MONTH,true)
                    childNodeInfo.recycle()
                    return
                }
                if (childNodeInfo.childCount>1){
                    val mHashSet = mCurrentMapSet[childContent]?: LinkedHashSet()
                    for (j in 0 until childNodeInfo.childCount){
                        val  viewNodeInfo = childNodeInfo.getChild(j) ?: continue
                        val viewContent = viewNodeInfo.contentDescription  ?:continue
                        if (viewContent.contains("订单详情")
                            &&viewContent.contains("...")){
                            nodeOnClick(viewNodeInfo)
                            viewNodeInfo.refresh()
                        }
                        viewNodeInfo.contentDescription?.let {
                            mHashSet.add(viewContent.toString())
                        }
                        if (j==childNodeInfo.childCount-1){
                            mCurrentMapSet[childNodeInfo.contentDescription.toString()] = mHashSet
                            if (i==scrollNodeInfo.childCount-1
                                &&scrollNum==0){
                                if (scrollNodeInfo.isScrollable){
                                    //滚动试图向下
                                    loopScroll(scrollNodeInfo,SCROLL_TIMER)
                                }
                            }
                        }
                    }
                }else{
                    if (i==scrollNodeInfo.childCount-1
                        &&scrollNum==0 && scrollNodeInfo.isScrollable){
                        //滚动试图向下
                        loopScroll(scrollNodeInfo,SCROLL_TIMER)
                    }
                }
            }
        }
    }

    private fun addDao() {
        viewModelScope.launch(Dispatchers.IO) {
            mCurrentMapSet.forEach{(key, value) ->
                val accessInfo =  accessDao.query(key)?:AccessInfo()
                accessInfo.content = key
                accessInfo.time = getTime(key)
                Log.e(TAG,"${accessInfo.time} ---${accessInfo.content}")
                val valueList = value
                for (viewContent in valueList){

                    if (viewContent.trim() == "回复"){
                        continue
                    }
                    if (viewContent.trim() == "申诉"){
                        continue
                    }
                    if (viewContent.trim() == "联系顾客"){
                        continue
                    }
                    if (viewContent.trim() == "发券"){
                        continue
                    }
                    if (viewContent.trim() == "修改回复"){
                        continue
                    }
                    if (viewContent.contains("订单详情")){
                        accessInfo.orderDetails = viewContent
                    }else {
                        if (key.contains("追评")
                            &&accessInfo.chaseComments==null){
                            accessInfo.chaseComments = viewContent
                        }else {
                            accessInfo.merchantReplied = viewContent
                        }
                    }
                }
                Log.d(TAG,"添加数据库$accessInfo")
                if (accessDao.query(key)==null){
                    accessDao.insertAll(accessInfo)
                    mCurrentMapSet.remove(key, value)
                }else{
                    accessDao.update(accessInfo)
                    mCurrentMapSet.remove(key, value)
                }

            }
        }
    }

    private var mRunnable : Runnable?=null
    private fun loopScroll(scrollNodeInfo : AccessibilityNodeInfo,timer:Long){
        scrollNum+=1
        mRunnable = Runnable {
            addDao()
            Log.d(TAG,"滚动试图向下    ：  ${scrollNodeInfo.contentDescription}")
            if (isScrollBottom == 0){
                scrollNodeInfo.performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD)
                loopScroll(scrollNodeInfo,SCROLL_TIMER)
                isScrollBottom++
            }else{
                isClickRepay.set(true)
                PreferencesUtil.putBoolean(mService,Config.YES_REPLAY,true)
                scrollNum = 0
                scrollNodeInfo.performAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD)
                mRunnable?.let { mHandler.removeCallbacks(it) }
            }
        }
        mRunnable?.let {
            mHandler.postDelayed(it,timer)
        }
    }

}